/*-------------------------------------------------------------------------

***************** Modification History ***********************************
   @doc
   @module Transact.c - Transaction functionality |
   @end

$Log: /SoftPay/SPK2SIM/Source/Tran/transact.c $
**************************************************************************

   Copyright (C) 1999 by VeriFone, Inc.

   All rights reserved.  No part of this software may be reproduced,
   transmitted, transcribed, stored in a retrieval system, or translated
   into any language or computer language, in any form or by any means,
   electronic, mechanical, magnetic, optical, chemical, manual or otherwise,
   without the prior written permission of VeriFone, Inc.

---------------------------------------------------------------------------*/
#define VSTRAN_C

#include <applidl.h>
#include <aclconio.h>
#include <aclstr.h>
#include <dbmgr.h>
#include <string.h>
#include <stdlib.h>
#include <varrec.h>
#include <power.h>
#include <battery.h>
#include <svc.h>

#include <project.h>
/** /#define DEBUG_VSTRAN*/
#ifdef DEBUG_VSTRAN
#define DEBUG_95
#endif

#include <define.h>
#include <transact.h>
#include <protocol.h>
#include <sizes.h>
#include <comm.h>
#include <modem.h>
#include <modemmsg.h>
#include <bdt.h>
#include <hdt.h>
#include <tct.h>
#include <trt.h>
#include <mht.h>
#include <tblutil.h>
#include <pct.h>
#include <sdt.h>
#include <msgshf.h>
#include <oper.h>
#include <operate.h>
#include <msg.h>
#include <mdlfuncs.h>
#include <msgfuncs.h>
#include <form.h>
#include <pform.h>
#include <fields.h>
#include <table.h>
#include <tran.h>
#include <funcids.h>
#include <ui.h>
#include <entry.h>
#include <print.h>
#include <spdebug.h>
#include <stats.h>
#include <retry.h>
#include <vidnld.h>
#include <multilng.h>
#include <codesec.h>
#include <counter.h>
#include <pcounter.h>
#include <funcs.h>
#include <pinpad.h>
#include <date.h>
#include <confio.h>
#include <accum.h>
#include <gds.h>
#ifdef EMV_MODULE
#include <emvfuncs.h>
#endif
#ifdef VXEMVAPP
/* No need to include here at this moment  */
/* #include <vxemvap.h>*/
#endif

extern int inNoDisp;
extern int trancount;
#ifdef EMV_MODULE
extern void vdEMVRemoveCard(void);
#endif
#ifdef VXEMVAPP
//extern int inVXEMVAPRemoveCard(void (*vdPromptManager)(int));
extern int inVXEMVAPRemoveCard(void (*vdPromptManager)(unsigned short));
//extern void vdPromptManager(int inCondition);
extern void vdPromptManager(unsigned short usCondition);
extern int inEMVAPIRemoveCard(TRANSACTION_OBJECT *pobTran);
#endif

/*********************************************************************************************
* @func VS_BOOL | fRefundTrans |
*       Checks GGCode() for Refund posibilities
*
* @parm TRANSACTION_OBJECT *| pobTran |
*       Transaction object
*
* @rdesc return values.
* @flag VS_BOOL |  VS_TRUE, VS_FALSE
* @end
**********************************************************************************************/

VS_BOOL fRefundTrans(TRANSACTION_OBJECT* pobTran) {
    if (pobTran->srBRec.inType == CREDIT_TRAN)
        return(VS_TRUE);
    return(VS_FALSE);
}

/*********************************************************************************************
* @func VS_BOOL | fRefundTrans |
*       Checks GGCode() for Phone posibilities
*
* @parm TRANSACTION_OBJECT *| pobTran |
*       Transaction object
*
* @rdesc return values.
* @flag VS_BOOL |  VS_TRUE, VS_FALSE
* @end
**********************************************************************************************/

VS_BOOL fPhoneTrans(TRANSACTION_OBJECT* pobTran) {
    switch (inGGCode()) {
    case    PHONE:
    case    VOID_PHONE_OFFLINE:
    case    ADJUST_PHONE_OFFLINE:
        return(VS_TRUE);
    }
    return(VS_FALSE);
}

/*********************************************************************************************
* @func int | inInitTran |
*       Sets the transaction type and get the display string
*
* @parm TRANSACTION_OBJECT *| pobTran |
*       Transaction object
*
* @rdesc return values.
* @flag int |  VS_SUCCESS, VS_ERR
* @end
**********************************************************************************************/

int inInitTran(TRANSACTION_OBJECT* pobTran) {
    long lnAvailSz;

    /** /pdebug (("--inInitTran--"));*/

    /* Disable auto answer */
    inAutoAnswerOff();

    if ((inGGCode() == REFUND) && (pobTran->srBRec.inTranCardType == DEBIT_CARD)) {
        vdSGCode(REFUND_DEBIT);
        pobTran->srBRec.lnMessage = REFUND_DEBIT_MSG;
    }

    if (inLoadTRTRec(pobTran, pobTran->inTransactionCode) < 0) {
        vdDisplayMessageFromFile(TRANS_NOT_SUPPORTED_MSG, ERROR_MSG);
        return(VS_ERR);
    }

#ifdef BATCH_DEFINED

    /*
     *      If Transaction will be stored to the batch, check for room.
     */
    //if (pobTran->srTRTRec.fDataCapture && (pobTran->srTRTRec.inTransactionCode!= VOID))
    if (fGetDataCapture(pobTran) && (shGetTransactionCode(pobTran) != VOID)) {
        /*
         *      Check Battery Charge status for Battery Operated terminal.
         */
        //qq if (srGDS.fBatteryOperated) {
        if (srGDS.fBatteryOperated && get_dock_sts() == HANDHELD_UNDOCKED) {
            if (get_battery_status() == CRITICAL_LEVEL) {
                vdClearNonTitleLines();
                vdDisplayErrorMessage(LOW_BATTERY_MSG21);
                if (get_dock_sts() == HANDHELD_UNDOCKED)
                    vdDisplayErrorMessage(MUST_DOCK_TERMINAL_MSG21);
                return(VS_ERR);
            }
        }

        /*
         *      Check for Available memory
         */
        if (fMemAvail(&lnAvailSz) != VS_TRUE) {
            vdDisplayMessageFromFile(NO_MEM_ERR_MSG, ERROR_MSG);
            return(VS_ERR);
        }
        if (lnAvailSz < (SAFE_LIMIT * SETTLE_SOON_SIZE)) {
            vdClearNonTitleLines();
            vdDisplayMessageFromFile(SETTLE_SOON_ERR_MSG, WARNING_MSG);
            vdClearStatusMessage();
        }

        /*
         *      Check against Host batch Limit, if there is one
         */
        if (inGetBatchNumLimit()) {
            int inNbrOfTransLeft;
            long lnHostTranCount = 0L;
            char szDisplayMessage[MESSAGE_SIZE + 1];

            inCheckBatchTotals(pobTran, &lnHostTranCount);
            inNbrOfTransLeft = inGetBatchNumLimit() - (int) lnHostTranCount;
            if (inNbrOfTransLeft <= 0) {
                memset(szDisplayMessage, 0, sizeof(szDisplayMessage));
                vdGetMessageFromFile(NO_MEM_ERR_MSG, szDisplayMessage);
                vdDisplayErrorString(szDisplayMessage);
                return(VS_ERR);
            } else if (inNbrOfTransLeft < (SETTLE_SOON_SIZE - SAFE_SIZE)) {
                vdClearNonTitleLines();
                vdDisplayMessageFromFile(SETTLE_SOON_ERR_MSG, WARNING_MSG);
                vdClearStatusMessage();
            }
        }
    }

    #endif // BATCH_DEFINED

    //if (!pobTran->srTRTRec.fAllowed)
    if (!fGetAllowed(pobTran)) {
        vdDisplayMessageFromFile(TRANS_NOT_ALLWD_ERR_MSG, ERROR_MSG);
        return(VS_ERR);
    }

    if (inCheckBannedCardType(pobTran) == VS_ERR)
        return(VS_ERR);

    pobTran->fAdjust = VS_FALSE;
    pobTran->fTipAdjust = VS_FALSE;
    /*if ((pobTran->srTRTRec.inTranType == ADJUST_DEBIT_TRAN) ||
        (pobTran->srTRTRec.inTranType == ADJUST_CREDIT_TRAN))*/
    if ((shGetTranType(pobTran) == ADJUST_DEBIT_TRAN) || (shGetTranType(pobTran) == ADJUST_CREDIT_TRAN)) {
        /* check to see if Tip key is pressed  kckc*/
        /* ADJUST_SALE_OFFLINE is only used in the TRT for Tip Adjust from the
           keypad */
        //if (pobTran->srTRTRec.inTransactionCode == TIP_ADJUST)
        if (shGetTransactionCode(pobTran) == TIP_ADJUST)
            pobTran->fTipAdjust = VS_TRUE;
    }

    //if (pobTran->srTRTRec.inTransactionCode!= VOID)
    if (shGetTransactionCode(pobTran) != VOID) {
        inInitPrintOption(pobTran);
        pobTran->srBKey.fOffline = fGetOffline(pobTran);
        //pobTran->srBRec.inType = pobTran->srTRTRec.inTranType;
        pobTran->srBRec.inType = shGetTranType(pobTran);
        if (strlen(pobTran->srBRec.szTranAbbrev) == 0)
            strcpy(pobTran->srBRec.szTranAbbrev, pobTran->srTRTRec.TranAbbrev);

        /*
         *      Set Surcharge in batch record for DEBIT & EBT
         */
        if (pobTran->srBRec.inTranCardType == DEBIT_CARD || pobTran->srBRec.inTranCardType == EBT_CARD)
            pobTran->srBRec.lnSChgAmount = (long) inGetSurCharge();
    }

#ifdef SHIFT_DEFINED
    vdSetShift(pobTran);                      /* Shift Processing */
#endif
    vdSGErrorMessage(0L);         /* Clear error message index */
    vdClearFooter();              /* Clear Footer */

    /*      Matt_V1 05/28/97 changed name  */
    vdMakeFooter(pobTran);

    return(VS_SUCCESS);
}


/*********************************************************************************************
* @func int | inUpdateTermInvAndHostInv |
*       Update the invoice number and host invoice number
*
* @parm TRANSACTION_OBJECT *| pobTran |
*       Transaction object
*
* @rdesc return values.
* @flag int |  VS_SUCCESS, VS_ERR
* @end
**********************************************************************************************/

int inUpdateTermInvAndHostInv(TRANSACTION_OBJECT* pobTran) {
    /** /pdebug(("--inUpdateTermInvAndHostInv--"));*/

    /* don't increment invoice nor host inv numbers on same card close tabs */
    /* Don't increment invoice nor host inv numbers on ISDN Test Transaction */
    if (pobTran->srBRec.fCloseTabSameCard == VS_TRUE || inGGCode() == ISDN_TEST_TRANSACTION) {
        /** /pdebug (("  No Inc"));*/
        return(VS_SUCCESS);
    }

    /* don't increment invoice number on adjust entries */
    //if ((pobTran->srTRTRec.fIncInvNum) && (!pobTran->fAdjust) && (!pobTran->fTipAdjust) &&  (inGetTCTKeyInvNum() == VS_FALSE))
    if ((fGetIncInvNum(pobTran)) && (!pobTran->fAdjust) && (!pobTran->fTipAdjust) && (fGetKeyInvNum() == VS_FALSE)) {
        /** /pdebug (("  Do Inc Inv"));*/
        if (inIncInvNum())
            return(VS_ERR);
    }

    /* don't increment host invoice number on adjust entries */
    if (fGetIncHostInvNum(pobTran)) {
        /** /pdebug (("  Do Inc Seq"));*/
        if (inIncHostInvNum())
            return(VS_ERR);
    }

    /** /pdebug(("Out Inv=%ld.",pobTran->srBKey.lnInvNum));*/
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inTransactions |
*       The mother of all transactions.
*
* @parm TRANSACTION_OBJECT *| pobTran |
*       Transaction object
*
* @rdesc return values.
* @flag int |  VS_SUCCESS, VS_ERR
* @end
**********************************************************************************************/

int inTransactions(TRANSACTION_OBJECT* pobTran) {
    int inResult;
    char szRespMsg[RESP_MSG_SIZE + 1];
    PFI_VOID pinCustomErrorFunction;

    /** /pdebug(("--inTransactions--"));*/

    inResult = inInitTran(pobTran);

    if (inResult == VS_SUCCESS) {
        if ((inResult = inRunEngine(pobTran->srTRTRec.shFieldFuncPtr, pobTran)) != VS_SUCCESS) {
#ifdef PINPAD_DEFINED

            if (inGetPINPadType() != NO_PINPAD)
                obPinPad.vdSendAbortToPINPad();

#endif /* PINPAD_DEFINED */

#ifdef EMV_MODULE

            if (pobTran->inChipStatus == EMV_CARD)
                vdEMVRemoveCard();
#endif /* EMV_MODULE */
#ifdef VXEMVAPP
/*  Don't remove card here.... Let see what happen....
	if (pobTran->inChipStatus == EMV_CARD)
		inVXEMVAPRemoveCard(vdPromptManager);
*/
#endif /* VXEMVAPP */

           if (obCommunication.inEnd)
               obCommunication.inEnd(&obCommunication);
            if (fGetAutoAnswer())
                SVC_WAIT(4000);

            if ((pinCustomErrorFunction = inGetFunctionPointer(CUSTOM_ERROR_FUNCTION)) != NULL_PFI)
                inResult = pinCustomErrorFunction();
            else if (inResult != VS_ESCAPE) {
                inResult = clrscr();
                vdGGRespMsg(szRespMsg);
                if (strlen(szRespMsg) > 0) {
                    vdDisplayResponseString(szRespMsg);
                    //              BT_TRACE ('H', szRespMsg);
                } else if (lnGGErrorMessage()) {
                    vdGetMessageFromFile(lnGGErrorMessage(), szRespMsg);
                    //                    BT_TRACE ('H', szRespMsg);
                    vdDisplayErrorMessage(lnGGErrorMessage());
                }
		//jrd meca spqalog016
		//KiaSoon 150206: To add in EMV_EASY_ENTRY_CARD to enable Pls Remove Card on terminal.
		if ((pobTran->inChipStatus == EMV_CARD) || (pobTran->inChipStatus == EMV_EASY_ENTRY_CARD))
			{
				clrscr();
				inEMVAPIRemoveCard(pobTran);
			}
		  /*inVXEMVAPRemoveCard(vdPromptManager);*/ //Not required here as this is mapped to separate ID and called in TRT flow
            }
		//jrd meca spqalog016
	    /* else if (inResult == VS_ESCAPE)
	     {
	     		if (pobTran->inChipStatus == EMV_CARD)
			{
				clrscr();
				inEMVAPIRemoveCard(pobTran);
			}
	     }*/


        }
    }

    INCREMENT_TRANS_COUNT;
    inAutoAnswerInit(pobTran);
    /** /pdebug(("--inTransactions DONE--"));*/

    return(inResult);
}

/*********************************************************************************************
* @func void | vdSetShift |
*       Set Shift # for batch based on Shift Processing Type
*
* @parm TRANSACTION_OBJECT *| pobTran |
*       Transaction object
* @end
**********************************************************************************************/

void vdSetShift(TRANSACTION_OBJECT* pobTran) {
#ifdef SHIFT_DEFINED
    int inSDTRec,
    inRetVal;
    long lnCurrentTime;
    char chShift = '0';
    char szTime[TIME_SIZE + 1];
    long ln2359 = 2359L;              /* for one minute before midnight */
    long ln0000 = 0L;                   /* for midnight */

    /** /pdebug (("VdSetShift"));*/
    /*
     *      For AUTO Shift Processing search the SDT for a match
     *      otherwise Shift Number is 0.
     */

    if (inGetShiftType() == AUTO_SHIFT) {
        /* Load current time, drop seconds value */
        vdGetTime(szTime);
        szTime[4] = NULL_CH;
        lnCurrentTime = atol(szTime);
        /*
         *      Loop through records for match
         */
        inSDTRec = 0;
        while (1) {
            inRetVal = inLoadConfRec(SDT_FILE_NAME, SIZE_SDT_REC, inSDTRec, (char *) &srSDTRec);
            if (inRetVal == VS_ERROR)
                break;

            if (str2long(srSDTRec.szStartTm) <= str2long(srSDTRec.szEndTm)) {
                if (lnCurrentTime >= str2long(srSDTRec.szStartTm) && lnCurrentTime <= str2long(srSDTRec.szEndTm)) {
                    chShift = srSDTRec.chShift;
                    break;
                }
            }
            /*  start time is before midnight and end time is after midnight */
            if (str2long(srSDTRec.szStartTm) > str2long(srSDTRec.szEndTm)) {
                if ((lnCurrentTime >= (str2long(srSDTRec.szStartTm)) && (lnCurrentTime <= ln2359)) || (lnCurrentTime <= (str2long(srSDTRec.szEndTm)) && (lnCurrentTime >= ln0000))) {
                    chShift = srSDTRec.chShift;
                    break;
                }
            }

            ++inSDTRec;
        }
    } else if (inGetShiftType() == MANUAL_SHIFT) {
        /*
         *      For MANUAL SHift Processing, just load the
         *      current shift number.
         */
        chShift = chGetCurrentShift();
    }

    pobTran->srBKey.chShift = chShift;
    return;
#endif
} /* End of vdSetShift () */

/*********************************************************************************************
* @func void | vdSetTranError |
*       Set Error Number and Load Resp Msg Buffer
*
* @parm long| lnErrMsgID |
*       Error Message
* @end
**********************************************************************************************/

void vdSetTranError(long lnErrMsgID) {
    char szFailMsg[MESSAGE_SIZE + 1];
    TRANSACTION_OBJECT* pobTran;

    /** changed 03/29/99 **/

    pobTran = pstGet_pobTran();

    if (pobTran == NULL)
        return;

    //  Remove following line to correct for double display of error message
    //    vdSGErrorMessage(lnErrMsgID);
    vdGetMessageFromFile(lnErrMsgID, szFailMsg);
    strlcpy(pobTran->szRespMsg, szFailMsg, RESP_MSG_SIZE);

    return;
} /* End of vdSetTranError () */

/*********************************************************************************************
* @func int | inDemoFunction |
*           Function which runs the function assigned to the function id DEMO_FUNCTION
*
*
* @parm TRANSACTION_OBJECT *| pobTran |
*       Transaction object
*
* @rdesc return values.
* @flag int |  VS_SUCCESS, VS_ERR
* @end
**********************************************************************************************/

int inDemoFunction(TRANSACTION_OBJECT* pobTran) {
    return(inRunFunction(pobTran, DEMO_FUNCTION));
}

/*
********************************************************************************************
* @func int | inDefaultDemoFunction  |
*       Base default demo function, displays communication messages and response message
*
*
* @parm TRANSACTION_OBJECT *| pobTran |
*       Transaction object
* @end
**********************************************************************************************/


int inDefaultDemoFunction(TRANSACTION_OBJECT* pobTran) {
#ifndef IMAM_REMOVE
    char szDispMsg[RESP_MSG_SIZE];
    char szAppCode[RESP_MSG_SIZE + 1];
    int inLen;
    int inChar;


    if (!fGetOffline(pobTran)) {
        pause(30);

        vdDisplayMessageFromFile(CONNECTED_MSG21, STATUS_MSG);
        pause(50);
        vdDisplayMessageFromFile(TRANSMITTING_MSG21, STATUS_MSG);
        pause(50);
        vdDisplayMessageFromFile(RECEIVING_MSG21, STATUS_MSG);
        pause(50);
        trancount++;
        sprintf(srRcpt.unFrm.srReceipt.szApprovalCode, "DEMO%02d", trancount);
        strcpy(pobTran->srBRec.szAuthCode, srRcpt.unFrm.srReceipt.szApprovalCode);
    }

    if (inIncSTAN() != VS_SUCCESS)
        return(VS_ERR);
    pobTran->srBRec.lnSTAN = lnGetSTAN();

    vdGetMessageFromFile(TRANS_APP_MSG, szDispMsg);
    if (get_font_mode() == 2) {
        char szSpace[4 + 1];
        szSpace[0] = 0x01; szSpace[1] = 0x20; szSpace[2] = 0x00;
        strcat(szDispMsg, szSpace);
        strcpy(szAppCode, "Demo"); //vdGetMessageFromFile( DEMO_TRAINING2_MSG, szAppCode);
    } else {
        strcat(szDispMsg, " ");
        inLen = strlen(szDispMsg);
        vdGetMessageFromFile(DEMO_TRAINING2_MSG, &szDispMsg[inLen]);
    }

    if ((get_font_mode() == 2) && (getgrid() == 0)) {
        vdDisplayAt(obDisp.inHomeCol, obDisp.inStatusLine, szDispMsg, CLR_EOL);
        vdDisplayDataStr(szAppCode, obDisp.inStatusLine * 2, CLR_EOL, ML_RIGHT);
    } else
        vdDisplayStatusString(szDispMsg);

    pobTran->srBRec.inTransactionResult = AUTHORIZED;

    if (inGetPrinterType() == NOPRINTER || !fGetEnablePrinter() || !fGetPrintReceipt(pobTran)) {
        vdFlushKeyboardBuffer();
        while (((inChar = get_char()) != KEY_CR) && inChar != KEY_CANCEL)
            vdBeep();
    }

#endif //IMAM_REMOVE
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inInitPrintOption |
*       Set Error Number and Load Resp Msg Buffer
*
* @parm TRANSACTION_OBJECT *| pobTran |
*       Transaction object
*
* @rdesc return values.
* @flag int |  VS_SUCCESS, VS_ERR
* @end
**********************************************************************************************/

int inInitPrintOption(TRANSACTION_OBJECT* pobTran) {
    /*
     *      Default to No Printer, get out if there is None.
     */
    pobTran->srBRec.inPrintOption = PRT_NONE;

    if (inGetPrinterType() == NOPRINTER || !fGetEnablePrinter())
        return(VS_SUCCESS);

    /* Set the transaction print options to the TRT setting for normal transaction.
       PRE_AUTH and PRE_COMP use TCT flag instead of TRT flag to determine print so
       that merchant can control this feature.
       FPS conditions will be imposed later */
    if (inGGCode() == PRE_AUTH) {
        if (fGetOpenTabOptRec())
            pobTran->srBRec.inPrintOption = PRT_MERCH;
    } else if ((pobTran->srBRec.fCloseTabSameCard || pobTran->srBRec.fCloseTabNewCard)) {
        if (fPrintCloseTab(pobTran)) {
            pobTran->srBRec.inPrintOption = PRT_MERCH;
            if (inGetCustCopyOption() == PRT_CUST_CONFIRM)
                pobTran->srBRec.inPrintOption = PRT_BOTH_CONF_CUSTCOPY;
            if (inGetCustCopyOption() == PRT_CUST_AUTO)
                pobTran->srBRec.inPrintOption = PRT_BOTH_AUTO_CUSTCOPY;
        } else
            pobTran->srBRec.inPrintOption = PRT_NONE;
    } else if (fGetPrintReceipt(pobTran)) {
        pobTran->srBRec.inPrintOption = PRT_MERCH;
        if (inGetCustCopyOption() == PRT_CUST_CONFIRM)
            pobTran->srBRec.inPrintOption = PRT_BOTH_CONF_CUSTCOPY;
        if (inGetCustCopyOption() == PRT_CUST_AUTO)
            pobTran->srBRec.inPrintOption = PRT_BOTH_AUTO_CUSTCOPY;
    }

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inStoreTranFlexiData |
*
*       Store data to the Transation Object flexi record
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       Transaction Object structure pointer
*
* @parm int | inFieldID |
*       Flexi Record Field ID
*
* @parm unsigned char * | pchData |
*       Buffer to store
*
* @parm int | inLength |
*       lentgh pchData buffer.
*
* @rdesc return values.
*
* @flag int    |  VS_ERR, VAR_INSUFFICIENT_BUFFER_SPACE, or VS_SUCCESS.
* @end
**********************************************************************************************/

int inStoreTranFlexiData(TRANSACTION_OBJECT* pobTran,unsigned short uiFieldID,unsigned char* pchData,unsigned short shDataLength) {
    int inRetVal = VS_ERR;
 //jrd one source
    #ifdef __arm
    unsigned short      usLength;
    #endif
    #ifdef _TARG_68000
    unsigned int      usLength;
    #endif

    short shRetVal;
    unsigned char   ucType, ucAttributes;

    if ((shRetVal = shVarQueryField(pobTran->pchFlexiData, uiFieldID, &usLength, &ucType, &ucAttributes)) == VAR_NO_ERROR) {
        if ((shRetVal = shVarUpdateField(pobTran->pchFlexiData, uiFieldID, pchData, shDataLength)) == VAR_NO_ERROR)
            inRetVal = VS_SUCCESS;
    } else if (shRetVal == VAR_FIELD_NOT_FOUND) {
        if ((shRetVal = shVarAddField(pobTran->pchFlexiData, uiFieldID, pchData, shDataLength)) == VAR_NO_ERROR)
            inRetVal = VS_SUCCESS;
    }

    if (shRetVal == VAR_INSUFFICIENT_BUFFER_SPACE)
        inRetVal = (int) VAR_INSUFFICIENT_BUFFER_SPACE;

    return (inRetVal);
}

/*********************************************************************************************
* @func int | inGetTranFlexiData |
*
*       Retrieves data from the Transation Object flexi record
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       Transaction Object structure pointer
*
* @parm int | inFieldID |
*       Flexi Record Field ID
*
* @parm unsigned char * | pchData |
*       Buffer to store data
*
* @parm int | inMaxLength |
*       Size of pchData buffer.
*
* @rdesc return values.
*
* @flag int     |   - >0, size of data retrieved
*                   - VS_ERR, ERROR (errno set to Flexi Record Error Value)
* @end
**********************************************************************************************/
extern int errno;

int inGetTranFlexiData(TRANSACTION_OBJECT* pobTran,unsigned int uiFieldID,unsigned char* pchData,unsigned short shMaxLength) {
    int inRetVal = VS_ERROR;
    short shRetVal;
   //jrd one source
    #ifdef __arm
     unsigned short    usLength;
    #endif
    #ifdef _TARG_68000
     unsigned int    usLength;
    #endif


    if ((shRetVal = shVarGetField(pobTran->pchFlexiData, uiFieldID, pchData, shMaxLength, &usLength)) == VAR_NO_ERROR)
        inRetVal = (int) usLength;
    else
        errno = (int) shRetVal;

    return inRetVal;
}


int TRANSACT_CODE_CHECK(char* a,char* b,short* c,char* d,unsigned char* e) {
    GET_VER(a, b, c, d, e);
    return 1;
}

#undef VSTRAN_C


